package m.system;

import m.common.action.Action;
import m.common.action.ActionMeta;
import m.common.model.*;
import m.common.model.config.ModelConfig;
import m.common.model.util.ModelUtil;
import m.common.netty.HostNettyUtil;
import m.common.service.HostInfoService;
import m.system.cache.CacheUtil;
import m.system.cache.model.CacheSynch;
import m.system.exception.MException;
import m.system.task.TaskUtil;
import m.system.util.AnnotationUtil;
import m.system.util.ClassUtil;
import m.system.util.StringUtil;
import m.system.util.SystemUtil;
import org.quartz.SchedulerException;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class SystemInit {
	/**
	 * 设置数据库名称
	 *  tableSchema
	 */
	public static void setTableSchema(String tableSchema){
		ModelConfig.setTableSchema(tableSchema);
	}
	/**
	 * 初始化数据表结构缓存
	 *  modelPage
	 */
	@SuppressWarnings("unchecked")
	public static void initModel(String modelPack) throws ClassNotFoundException {
		SystemUtil.printlnIf(true,"初始化表结构>>>");
		if(!StringUtil.isSpace(modelPack)) {
			String[] packs=StringUtil.toArrayDedup(modelPack,",");
			List<Class<Model>> lastInit= new ArrayList<>();
			for (String pack : packs) {
				if (StringUtil.isSpace(pack)) continue;
				List<String> modelNames = ClassUtil.getAllQualifiedName4Class(pack);
				for (String modelName : modelNames) {
					Class<?> cc = Class.forName(modelName);
					if (Model.class.isAssignableFrom(cc)) {
						Class<Model> clazz = (Class<Model>) cc;
						TableMeta tm = AnnotationUtil.getAnnotation4Class(TableMeta.class, clazz);
						if (null != tm) {
							if (tm.isView()) {
								lastInit.add(clazz);
							} else {
								initModel(clazz, tm);
							}
						}
					}
				}
			}
			for(Class<Model> clazz : lastInit){
				TableMeta tm=AnnotationUtil.getAnnotation4Class(TableMeta.class,clazz);
				initModel(clazz,tm);
			}
		}
		//特殊表初始化
		initModel(CacheSynch.class,AnnotationUtil.getAnnotation4Class(TableMeta.class,CacheSynch.class));
		SystemUtil.printlnIf(true,"初始化表结构完成<<<");
	}
	private static <T extends Model> void initModel(Class<T> clazz,TableMeta tm){
		if(null!=tm) {
			Map<String,FieldMeta> fieldMap=AnnotationUtil.getAnnotationMap4Field(FieldMeta.class,clazz);
			Map<String,LinkTableMeta> linkTableMap=AnnotationUtil.getAnnotationMap4Field(LinkTableMeta.class,clazz);
			Map<String,QueryFieldMeta> queryFieldMap=AnnotationUtil.getAnnotationMap4Field(QueryFieldMeta.class,clazz);
			ModelConfig.fillModelInfo(clazz, tm, fieldMap, linkTableMap, queryFieldMap);
		}
	}
	/**
	 * 初始化数据库表结构
	 */
	public static void initModelTable() throws MException, SQLException {
		boolean isMain= HostInfoService.isMainHost();
		//HostInfo host=RuntimeData.getHostInfo();
		if(!isMain) return;
		
		for(Class<? extends Model> clazz : ModelConfig.getTableList()){
			ModelUtil.initModelTable(clazz);
		}
		//表初始化后
		CacheUtil.initSynch();
	}
	public static void initServerGroup(String ip,int port){
		if(!StringUtil.isSpace(ip)){
			SystemUtil.printlnIf(true,"主控主机地址：",ip);
			HostNettyUtil.openServer(port);
			HostNettyUtil.openClient(ip, port);
			HostNettyUtil.done();
		}else{
			HostInfo host=new HostInfo();
			host.setIpport(".");
			HostInfoService.setHostInfo(".", host);
			HostInfoService.setMainHost(".");
		}
	}
	public static void initClassRun(String initClass) throws Exception {
		if(StringUtil.isSpace(initClass)) return ;
		String[] clazzs=StringUtil.toArrayDedup(initClass,",");
		for (String clazz : clazzs) {
			if (StringUtil.isSpace(clazz.trim())) continue;
			ClassUtil.executeMethod(Class.forName(clazz.trim()).newInstance(), "execute");
		}
	}
	public static void initClassInit(String initClass) throws Exception {
		if(StringUtil.isSpace(initClass)) return ;
		String[] clazzs=StringUtil.toArrayDedup(initClass,",");
		for (String clazz : clazzs) {
			if (StringUtil.isSpace(clazz.trim())) continue;
			ClassUtil.executeMethod(Class.forName(clazz.trim()).newInstance(), "init");
		}
	}
	public static void taskClassRun(String taskClass) throws SchedulerException, ClassNotFoundException {
		List<String[]> list=new ArrayList<>();
		if(!StringUtil.isSpace(taskClass)) {
			String[] clazzs=StringUtil.toArrayDedup(taskClass,"&");
			for(String clazz : clazzs){
				String[] arr=clazz.split("\\|");
				if(arr.length==2){
					list.add(arr);
				}else{
					SystemUtil.printlnIf(true,"定时类配置错误!"+clazz);
				}
			}
		}
		TaskUtil.initTask(list);
	}
	@SuppressWarnings("unchecked")
	public static void initAction(String actionPack) throws ClassNotFoundException {
		if(StringUtil.isSpace(actionPack)) return ;
		String[] packs=StringUtil.toArrayDedup(actionPack,",");
		for (String pack : packs) {
			if (StringUtil.isSpace(pack)) continue;
			List<String> modelNames = ClassUtil.getAllQualifiedName4Class(pack);
			for (String modelName : modelNames) {
				Class<?> clazz = Class.forName(modelName);
				if (Action.class.isAssignableFrom(clazz)) {
					ActionMeta meta = AnnotationUtil.getAnnotation4Class(ActionMeta.class, clazz);
					if (null != meta) {
						RuntimeData.fillAction(meta.name(), (Class<Action>) clazz);
					}
				}
			}
		}
	}
}
